package cn.com.doone.common.uc.infrastructure.shiro;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.realm.ldap.JndiLdapRealm;
import org.apache.shiro.realm.ldap.LdapContextFactory;
import org.apache.shiro.realm.ldap.LdapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import cn.com.doone.common.uc.utils.PasswordUtils;

public class DooneOpenLdapRealm extends JndiLdapRealm implements InitializingBean {

	private static final Logger log = LoggerFactory.getLogger(JndiLdapRealm.class);
	
	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
	
		Object principal = token.getPrincipal();
		Object credentials = token.getCredentials();
		
		
		LdapContext ldapContext = null;
		try {
			ldapContext = ldapContextFactory.getSystemLdapContext();
			
			String username = (String) token.getPrincipal();
			String password  = new String((char[]) credentials);
			
			final SearchControls searchCtls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false); 
			// final SearchControls searchCtls = new SearchControls(); 
            final NamingEnumeration<SearchResult> search = ldapContext.search("DC=doone,DC=com,DC=cn", "(&(userPassword=" + PasswordUtils.openLdapMD5(password) + ")(uid=" + username + ")(status=1))", searchCtls);
            
            if (search.hasMore()) {
                /*final SearchResult next = search.next();
                
                String fullname = next.getNameInNamespace();
                ldapContext.addToEnvironment(Context.SECURITY_PRINCIPAL, fullname);
                ldapContext.addToEnvironment(Context.SECURITY_CREDENTIALS, PasswordUtils.md5Password(password));
                ldapContext.reconnect(null);*/
                return createAuthenticationInfo(token, principal, credentials, ldapContext);
            } else {
            	throw new NamingException();
            } 
			
			//context was opened successfully, which means their credentials were valid.  Return the AuthenticationInfo:
		} catch (Exception e) {
			throw new NamingException();
		} finally {
			LdapUtils.closeContext(ldapContext);
		}
	}

}
